package com.read.config;

import com.alibaba.fastjson.JSON;
import com.google.common.util.concurrent.RateLimiter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName MyGlobalFilter
 * @Description TODO
 * @Author young
 * @Date 2022-11-05 12:11
 * @Version 1.0
 **/
@Component
public class MyGlobalFilter implements GlobalFilter {
    //声明一个放置url的数组,需要对哪些路径下的请求放行
    public static List urlList = new ArrayList<>();

    //声明令牌桶, 进行限流操作
    RateLimiter rateLimiter = RateLimiter.create(20.0);

    //对请求 进行过滤处理
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //请求进入令牌桶获取令牌,如果获取到,则执行, 获取失败直接抛弃该请求
        boolean b = rateLimiter.tryAcquire();

        //1,获取到Request 和Response 返回,基于webflux
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

//        //获取请求的url,进行切割, 切割的url如果和user相同,则证明此接口不需要拦截,直接放行
//        URI uri = request.getURI();
//        String s = JSON.toJSONString(uri);
//        String[] split = s.split("/");
//        if (urlList.contains(split[1])){
//            return chain.filter(exchange);
//        }
        Map map = new HashMap<>();
        if (b) {
            //2,获取到请求头中的token
            String token = request.getHeaders().getFirst("token");
            if (StringUtils.isEmpty(token)) {
                //2.1 如果token为null,进行拦截
                map.put("msg","当前用户未登录!!");
                return response(response,map);
            } else {
                //此处的token是在使用jwt加密时, 生成的uuid,
                // 应该再从redis中进行获取到加密后的 jwt串  再调用工具类对token进行解析
                //如果解析失败,则拦截,  解析成功 则放行请求  return chain.filter(exchange);
                //此时抢到令牌,并且token解析成功,放行
                return chain.filter(exchange);
            }
        }else{
            //此时未抢到令牌,拦截
            map.put("msg","请求量过大,当前服务器繁忙,请稍后再试!!!");
            return response(response,map);
        }

    }



    public Mono<Void> response(ServerHttpResponse response,Object msg){
        //1,将msg转换为 string类型
        String s = JSON.toJSONString(msg);
        //2,将msg转换为 databuffer类型
        DataBuffer wrap = response.bufferFactory().wrap(s.getBytes(StandardCharsets.UTF_8));
        return response.writeWith(Flux.just(wrap));
    }

//    //声明构造方法,对于user服务下的接口,不需要认证,其他的接口都要进行认证
//    public MyGlobalFilter(){
//        urlList.add("user");
//    }

}
